/* tslint:disable */
<%- buildServiceImports(model, loadAccessToken, isIo) %>


/**
 * Api services for the `<%-: modelName %>` model.
<% if ( model.description ){ -%>
 *
 * **Details**
 *
 * <%-: model.description | replace:/\n/gi, '\n * ' %>
<% } -%>
 */
@Injectable()
export class <%-: modelName %>Api extends BaseLoopBackApi {

  constructor(
    <%- buildServiceDI(isIo) %>
  ) {
    super(http, <% if (isIo === 'enabled') { %> connection, <% } %> models, auth, searchParams, errorHandler);
  }
<% model.methods.forEach(function(action) {
 
  var methodName = action.name.split('.').join('$').replace('prototype$', '').replace(/::/g, '__');
  var httpVerb = (action.getEndpoints ? action.getEndpoints()[0].verb : action.getHttpMethod()).toUpperCase();
  var fullPath = action.getEndpoints ? action.getEndpoints()[0].fullPath : action.getFullPath();

  // all of these methods are extended from base service
  if (methodName.match(/(^create$|^createMany$|^find$|^replaceOrCreate$|^replaceById$|^upsert$|^upsertWithWhere$|^exists$|^findOne$|^findById$|^deleteById$|^updateAttributes$|^updateAll$|^count$|^createChangeStream$)/)) { return; }

  if (!model.sharedClass.ctor.settings.sdk.blacklist[methodName]) {
  ngdocForMethod(modelName, methodName, action, httpVerb, fullPath); 

  // SET URL PARAMS
  var urlParams = action.accepts;
  // SET POST BODY
  var postData;
  if (httpVerb == 'POST' || httpVerb == 'PUT' || httpVerb == 'PATCH') {
    postData = action.accepts;
  }
  // SET ROUTE PARAMS
  var routeParams = action.accepts
-%>
  public <%- normalizeMethodName(methodName) %>(<%- buildMethodParams(model, methodName, action.accepts) %>): Observable<<%- buildObservableType(model, action)  %>> {
    let _method: string = <%-: httpVerb | q %>;
    let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() +
    <%-: fullPath | q %>;
    let _routeParams: any = {<%- buildRouteParams(routeParams) %>};
    let _postBody: any = {<%- buildPostBody(postData) %>};
    let _urlParams: any = {};<%-
    buildUrlParams(model, methodName, urlParams) %><%
    if (model.isUser && methodName === 'logout') { %>
    this.auth.clear(); <%
    } -%>

    let result = this.request(_method, _url, _routeParams, _urlParams, _postBody, null, customHeaders)<%
if (model.isUser && methodName === 'login') { %>
      .map(
        (response: any) => {
          response.ttl = parseInt(response.ttl);
          response.rememberMe = rememberMe;
          this.auth.setToken(response);
          return response;
        }
      );
      return result;
      <%
} else if (methodName.match(/(^create$|upsert|^findBy|^findOne$)/g)) { %>;
    return result.map((instance: <%- modelName %>) => new <%-: modelName %>(instance));<%
} else if (methodName.match(/(^createMany$|^find)/g)) { %>;
    return result.map((instances: Array<<%- modelName %>>) =>
        instances.map((instance: <%- modelName %>) => new <%-: modelName %>(instance))
    );<%
} else { %>;
    return result;<%
} %>
  }
<% if ( isIo === 'enabled' && 
       (model.sharedClass.ctor.settings.mixins && model.sharedClass.ctor.settings.mixins.PubSub) && 
      !methodName.match(/log(in|out)/g)  &&
       methodName !== 'resetPassword' &&
       httpVerb !== 'GET' &&
       httpVerb !== 'HEAD'){
-%>

  public on<%- normalizeMethodName(methodName, true) %>(<%- buildMethodParams(model, methodName, action.accepts, true) %>): Observable<<%- buildObservableType(model, action)  %>> {
    let _method: string = <%-: httpVerb | q %>;
    let _url: string = "/" + LoopBackConfig.getApiVersion() +
    <%-: fullPath | q %>;
    let _routeParams: any = {<%- buildRouteParams(routeParams.filter(function(param) { return param.arg !== 'fk'; })) %>};
    let _postBody: any = {};
    let _urlParams: any = {};
    return this.request(_method, _url, _routeParams, _urlParams, _postBody, true);
  }
<% }} -%>
<% }); // model.methods.foreach -%>
<% if (model.isUser) { -%>
  /**
   * @ngdoc method
   * @name <%- moduleName %>.<%- modelName %>#getCurrent
   * @methodOf <%- moduleName %>.<%- modelName %>
   *
   * @description
   *
   * Get data of the currently logged user. Fail with HTTP result 401
   * when there is no user logged in.
   *
   * @returns object An empty reference that will be
   *   populated with the actual data once the response is returned
   *   from the server.
   */
  public getCurrent(filter: LoopBackFilter = {}): Observable<any> {
    let _method: string = "GET";
    let _url: string = LoopBackConfig.getPath() + "/" + LoopBackConfig.getApiVersion() + <%-: model.getPath() | q %> + "/:id";
    let id: any = this.auth.getCurrentUserId();
    if (id == null)
    id = '__anonymous__';
    let _routeParams: any = { id: id };
    let _urlParams: any = {};
    let _postBody: any = {};
    if (filter) _urlParams.filter = filter;
    return this.request(_method, _url, _routeParams, _urlParams, _postBody);
  }
  /**
   * Get data of the currently logged user that was returned by the last
   * call to {@link <%- moduleName %>.<%- modelName %>#login} or
   * {@link <%- moduleName %>.<%- modelName %>#getCurrent}. Return null when there
   * is no user logged in or the data of the current user were not fetched
   * yet.
   *
   * @returns object An Account instance.
   */
  public getCachedCurrent() {
    return this.auth.getCurrentUserData();
  }
  /**
   * Get data of the currently logged access tokern that was returned by the last
   * call to {@link <%- moduleName %>.<%- modelName %>#login}
   *
   * @returns object An AccessToken instance.
   */
  public getCurrentToken(): AccessToken {
    return this.auth.getToken();
  }
  /**
   * @name <%- moduleName %>.<%- modelName %>#isAuthenticated
   *
   * @returns {boolean} True if the current user is authenticated (logged in).
   */
  public isAuthenticated() {
    return !(this.getCurrentId() === '' || this.getCurrentId() == null || this.getCurrentId() == 'null');
  }

  /**
   * @name <%- moduleName %>.<%- modelName %>#getCurrentId
   *
   * @returns object Id of the currently logged-in user or null.
   */
  public getCurrentId() {
    return this.auth.getCurrentUserId();
  }
<% } -%>

  /**
   * The name of the model represented by this $resource,
   * i.e. `<%- modelName %>`.
   */
  public getModelName() {
    return <%-: modelName | q %>;
  }
}
<%
function getJsDocType(arg) {
  return arg.type;
}

function ngdocForMethod(modelName, methodName, action, httpVerb, fullPath) {
   // always add an empty line before the ngdoc comment:
-%>

  /**
<% if (action.deprecated) { -%>
   * @deprecated <%- action.deprecated %>
<% } -%>
<% if (!action.description) {
action.description =  '<em>\n' +
  '(The remote method definition does not provide any description.)\n' +
  '</em>';
} -%>
   * <%-: action.description | replace:/\n/g, '\n         * ' %>
<%
var params = action.accepts.filter(param => {
    return !paramIsContext(param);
});

var postData;
if (httpVerb == 'POST' || httpVerb == 'PUT' || httpVerb == 'PATCH') {
  params = params.filter(function(arg) {
    return arg.http && (arg.http.source == 'query' || arg.http.source == 'path');
  });
  postData = action.accepts.filter(function(arg) {
    return params.indexOf(arg) == -1 && !paramIsContext(arg) && !paramIsFunction(arg);
  });
}
-%>
<% if (params.length != 0) {
  params.forEach(function(arg) { -%>
   *
   * @param {<%- getJsDocType(arg) %>} <%- arg.arg %> <%-
(arg.description ? (Array.isArray(arg.description) ? arg.description.join('\n') : arg.description) : '').replace(/\n/g, '\n         *   ') %>
<%   if (model.isUser && methodName === 'login' && arg.arg === 'include') { -%>
   *   Default value: `user`.
<%   } -%>
<% }); } -%>
<% if (model.isUser && methodName === 'login') { -%>
   *
   *  - `rememberMe` - `boolean` - Whether the authentication credentials
   *     should be remembered in localStorage across app/browser restarts.
   *     Default: `true`.
<% } -%>
<% if (postData) { -%>
   *
   * @param {object} data Request data.
<% if (postData.length == 0) { -%>
   *
   * This method does not accept any data. Supply an empty object.
<% } else if (postData.length == 1 && postData[0].http &&
      postData[0].http.source == 'body' &&
      !postData[0].description) { -%>
   *
   * This method expects a subset of model properties as request parameters.
<% } else {
postData.forEach(function(arg) { -%>
   *
   *  - `<%- arg.arg %>` – `{<%- getJsDocType(arg)  %>}` - <%-
(arg.description ? (Array.isArray(arg.description) ? arg.description.join('\n') : arg.description) : '').replace(/\n/g, '\n         *   ') %>
<%   });
  }
} -%>
   *
<% var returnType = action.isReturningArray() ? 'object[]': 'object'; -%>
   * @returns {<%- returnType %>} An empty reference that will be
   *   populated with the actual data once the response is returned
   *   from the server.
   *
<% if (!action.returns || action.returns.length == 0) { -%>
   * This method returns no data.
<% } else if (action.returns[0].root) { -%>
<%   if (action.returns[0].description) { -%>
   * <%- action.returns[0].description
.replace(/\n/g, '\n   * ').trimRight() %>
<%   } else { -%>
   * <em>
   * (The remote method definition does not provide any description.
   * This usually means the response is a `<%- modelName %>` object.)
   * </em>
<%   } -%>
<% } else { -%>
   * Data properties:
<%   action.returns.forEach(function(arg) { -%>
   *
   *  - `<%- arg.arg %>` – `{<%- getJsDocType(arg)  %>}` - <%-
(arg.description ? (Array.isArray(arg.description) ? arg.description.join('\n') : arg.description) : '').replace(/\n/g, '\n         *   ') %>
<%   });
   }
-%>
   */
<% } // end of ngdocForMethod -%>
